package com.kyh.util.redis;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;

import com.kyh.util.ApplicationContext;

public class RedisUtil {

	private static final Logger logger = Logger.getLogger(RedisUtil.class);

	private static final RedisUtil cacheUtil;

	static {
		cacheUtil = new RedisUtil();
	}
	
	public static String KEY_TOKEN = "token_";
	public static String KEY_ID = "id_";

	public static RedisUtil getInstance() {
		return cacheUtil;
	}

	private RedisTemplate<String, Object> redisTemplate;

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public RedisUtil() {
		redisTemplate = (RedisTemplate) ApplicationContext.getBean("redisTemplate");
	}
	
	private void add(String key, String testValue) {
		logger.debug("添加测试缓存数据");
		
		//获取各个属性值
		final byte[] bytes = (key).getBytes();
		
		final Map<byte[], byte[]> map = new HashMap<byte[], byte[]>();
		map.put("testKey".getBytes(), testValue.getBytes());
		
		//将各属性值存入缓存
		redisTemplate.execute(new RedisCallback<String>() {
			public String doInRedis(RedisConnection conn) throws DataAccessException {
				boolean isInit = conn.exists(bytes);
				conn.hMSet(bytes, map);
				if(!isInit){
					conn.expire(bytes, 1800);
				}
				return "success";
			}
		});
	}
	
	
	
	private String get(String key) {
		final byte[] bytes = (key).getBytes();
		
		return redisTemplate.execute(new RedisCallback<String>() {
			public String doInRedis(RedisConnection conn) throws DataAccessException {
				if (!conn.exists(bytes)) {
					return null;
				}
				List<byte[]> list = conn.hMGet(bytes,
						"testKey".getBytes()); //0
				if (list.size() <=0) {
					return null;
				}
				
				return new String(list.get(0));
			}
		});
	}
	
	public void remove(String rowStr) {
		
		final byte[] bytes = (rowStr).getBytes();
		
		//从缓存移除
		redisTemplate.execute(new RedisCallback<String>() {
			public String doInRedis(RedisConnection conn) throws DataAccessException {
				boolean isInit = conn.exists(bytes);
				if (isInit == true) {
					conn.del(bytes);
				}
				return "success";
			}
		});
	}
	
	public String get(String rowStr, String keyStr) {
		final byte[] uidBytes = (rowStr).getBytes();
		
		return redisTemplate.execute(new RedisCallback<String>() {
			public String doInRedis(RedisConnection conn) throws DataAccessException {
				if (!conn.exists(uidBytes)) {
					return "-1";
				}
				List<byte[]> list = conn.hMGet(uidBytes,
						keyStr.getBytes()); //0
				if (list.size() <=0) {
					return "-1";
				}
				
				return new String(list.get(0));
			}
		});
	}
	
	/**
	 * 
	 * @param rowStr
	 * @param keyStr
	 * @param value
	 */
	public void updateToken(String rowStr, String keyStr, String value) {
		logger.debug("更新uidStr的token_");
		
		//获取各个属性值
		final byte[] uidBytes = (rowStr).getBytes();
		
		final Map<byte[], byte[]> map = new HashMap<byte[], byte[]>();
		map.put(keyStr.getBytes(), value.getBytes());
		
		//将各属性值存入缓存
		redisTemplate.execute(new RedisCallback<String>() {
			public String doInRedis(RedisConnection conn) throws DataAccessException {
				conn.hMSet(uidBytes, map);
				return "success";
			}
		});
	}

    /**
     * 判断key是否存在
     */
    public boolean hasKey(String keyName) {
        try {
            return redisTemplate.hasKey(keyName);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    
	/**
	 * 将数据按秒数存入redis，过期清除
	 * @param rowStr key值
	 * @param keyStr map内对应的名称key
	 * @param value map内对应的value值
	 * @param seconds 秒数,默认300秒（5分钟）
	 */
	public void addExpire(String rowStr, String keyStr, String value,Long seconds) {
		logger.debug("更新uidStr的token_");
		
		//获取各个属性值
		final byte[] uidBytes = (rowStr).getBytes();
		
		final Map<byte[], byte[]> map = new HashMap<byte[], byte[]>();
		map.put(keyStr.getBytes(), value.getBytes());
		
		//将各属性值存入缓存
		redisTemplate.execute(new RedisCallback<String>() {
			public String doInRedis(RedisConnection conn) throws DataAccessException {
				conn.hMSet(uidBytes, map);
				if(seconds!=null&&seconds!=0) {
					conn.expire(uidBytes, seconds);
				}else {
					conn.expire(uidBytes, 300L);
				}
				return "success";
			}
		});
	}
	
	
	public Boolean getExistsByKey(String key) {
		final byte[] bytes = (key).getBytes();
		
		return redisTemplate.execute(new RedisCallback<Boolean>() {
			public Boolean doInRedis(RedisConnection conn) throws DataAccessException {
				if (!conn.exists(bytes)) {
					return false;
				}
				
				return true;
			}
		});
	}
	
  
}
